package com.eternal.notification.ui;

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;

import com.afollestad.materialdialogs.MaterialDialog;
import com.eternal.base.data.RepositoryInjection;
import com.eternal.base.database.entity.Notification;
import com.eternal.base.global.ActivityEvent;
import com.eternal.base.utils.GuQiangUtil;
import com.eternal.framework.binding.command.BindingAction;
import com.eternal.framework.bus.Messenger;
import com.eternal.framework.component.BaseFragment;
import com.eternal.framework.utils.GsonUtils;
import com.eternal.framework.utils.Utils;
import com.eternal.notification.BR;
import com.eternal.notification.R;
import com.eternal.notification.databinding.FragmentAutomationBinding;
import com.eternal.notification.model.AutomationModel;
import com.eternal.widget.WheelView;
import com.eternal.widget.guqiang.IEffectBar;
import com.google.common.collect.Lists;

import java.util.ArrayList;

/**
 * Created by Administrator
 * On 2020/5/9
 * Description:
 * @author Administrator
 */
public class AutomationFragment extends BaseFragment<FragmentAutomationBinding, AutomationModel> {
    private String ok;
    private MutableLiveData<Boolean> now;

    @Override
    public int initContentView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return R.layout.fragment_automation;
    }

    @Override
    public int initVariableId() {
        return BR.autoModel;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Bundle arguments=getArguments();
        boolean isDegree=arguments.getBoolean(ActivityEvent.DEVICE_DEGREE);
        String temp=arguments.getString(ActivityEvent.NOTIFICATION);
        initView(isDegree, temp!=null);
        registerMessage();
        bindEvent();
        viewModel.init(RepositoryInjection.providerNotificationRepository(),
                arguments.getString(ActivityEvent.DEVICE_MAC) , arguments.getByte(ActivityEvent.DEVICE_PORT,(byte)0x0), GsonUtils.fromJson(temp, Notification.class), isDegree);
    }

    @Override
    public void onDestroyView() {
        unregisterMessage();
        super.onDestroyView();
    }

    private void initView(boolean isDegree, boolean showDelete){
        ArrayList<String> hours=initTime(1, 12, false);
        ArrayList<String> minus=initTime(0, 59, true);
        ArrayList<String> aps= Lists.newArrayList("AM", "PM");
        initStartTime(hours, minus, aps);
        initEndTime(hours, minus, aps);
        initTmpAndHum();
        initCycle();
        IEffectBar.Factory factory=new IEffectBar.Factory() {
            @Override
            public String getText(int value) {
                return GuQiangUtil.stringForTimeNoZero(value*10);
            }
        };
        binding.apCycleOff.setFactory(factory);
        binding.apCycleOn.setFactory(factory);
        factory=new IEffectBar.Factory() {
            @Override
            public String getText(int value) {
                return Utils.getString(R.string.tip_percent_num, value);
            }
        };
        binding.calHum.setFactory(factory);
        factory=new IEffectBar.Factory() {
            @Override
            public String getText(int value) {
                if(viewModel.isDegree){
                    return Utils.getString(R.string.tip_degree_num, value);
                }else{
                    return Utils.getString(R.string.tip_fah_num, value);
                }
            }
        };
        binding.calTmp.setFactory(factory);
        if(isDegree){
            String min="0℃",max="90℃";
            binding.cpHighTmp.setValue(min, max,0, 90);
            binding.cpLowTmp.setValue(min,max,0, 90);
        }else{
            String min="32℉", max="194℉";
            binding.cpHighTmp.setValue(min,max,32, 162);
            binding.cpLowTmp.setValue(min,max,32, 162);
        }
        if(showDelete){
            binding.btnDelete.setVisibility(View.VISIBLE);
        }
    }

    private void initCycle(){
        binding.apCycleOn.setListener(new IEffectBar.Listener() {
            @Override
            public void onDown(boolean isProgress) {

            }

            @Override
            public void onChange(int now) {

            }

            @Override
            public void onUp(boolean isProgress, int now) {
                viewModel.cycleOn.setValue((char) (now*10));
            }

            @Override
            public void onChecked(boolean b) {

            }
        });
        binding.apCycleOff.setListener(new IEffectBar.Listener() {
            @Override
            public void onDown(boolean isProgress) {

            }

            @Override
            public void onChange(int now) {

            }

            @Override
            public void onUp(boolean isProgress, int now) {
                viewModel.cycleOff.setValue((char) (now*10));
            }

            @Override
            public void onChecked(boolean b) {

            }
        });
    }

    private void initTmpAndHum(){
        binding.calTmp.setListener(new AbstractAdapter() {
            @Override
            public void onEndFirst(boolean isProgress,int value) {
                viewModel.hTmp.setValue((char) value);
            }

            @Override
            public void onEndLast(boolean isProgress,int value) {
                viewModel.lTmp.setValue((char) value);
            }

            @Override
            public void onFirstChecked(boolean b) {
                viewModel.hTmpSwitch.setValue(b);
            }

            @Override
            public void onLastChecked(boolean b) {
                viewModel.lTmpSwitch.setValue(b);
            }
        });
        binding.calHum.setListener(new AbstractAdapter() {
            @Override
            public void onEndFirst(boolean isProgress,int value) {
                viewModel.hHum.setValue((byte) value);
            }

            @Override
            public void onEndLast(boolean isProgress,int value) {
                viewModel.lHum.setValue((byte) value);
            }

            @Override
            public void onFirstChecked(boolean b) {
                viewModel.hHumSwitch.setValue(b);
            }

            @Override
            public void onLastChecked(boolean b) {
                viewModel.lHumSwitch.setValue(b);
            }
        });
    }

    private void initStartTime(ArrayList<String> hours, ArrayList<String> minus, ArrayList<String> aps){
        binding.wvStartHour.setData(hours);
        binding.wvStartHour.setOnSelectListener(new WheelView.OnSelectListener() {
            @Override
            public void endSelect(int id, String text) {
                viewModel.startHour.setValue((byte) id);
                viewModel.start.setValue(Utils.getString(R.string.notify_time, text,
                        binding.wvStartMin.getSelectedText(), binding.wvStartAmOrPm.getSelectedText()));
            }

            @Override
            public void selecting(int id, String text) {

            }
        });
        binding.wvStartMin.setData(minus);
        binding.wvStartMin.setOnSelectListener(new WheelView.OnSelectListener() {
            @Override
            public void endSelect(int id, String text) {
                viewModel.startMin.setValue((byte) id);
                viewModel.start.setValue(Utils.getString(R.string.notify_time,
                        binding.wvStartHour.getSelectedText(), text,
                        binding.wvStartAmOrPm.getSelectedText()));
            }

            @Override
            public void selecting(int id, String text) {

            }
        });
        binding.wvStartAmOrPm.setData(aps);
        binding.wvStartAmOrPm.setOnSelectListener(new WheelView.OnSelectListener() {
            @Override
            public void endSelect(int id, String text) {
                viewModel.startAp.setValue((byte) id);
                viewModel.start.setValue(Utils.getString(R.string.notify_time,
                        binding.wvStartHour.getSelectedText(), binding.wvStartMin.getSelectedText(),text));
            }

            @Override
            public void selecting(int id, String text) {

            }
        });
    }

    private void initEndTime(ArrayList<String> hours, ArrayList<String> minus, ArrayList<String> aps){
        binding.wvEndHour.setData(hours);
        binding.wvEndHour.setOnSelectListener(new WheelView.OnSelectListener() {
            @Override
            public void endSelect(int id, String text) {
                viewModel.endHour.setValue((byte) id);
                viewModel.end.setValue(Utils.getString(R.string.notify_time, text, binding.wvEndMin.getSelectedText(),
                        binding.wvEndAmOrPm.getSelectedText()));
            }

            @Override
            public void selecting(int id, String text) {

            }
        });
        binding.wvEndMin.setData(minus);
        binding.wvEndMin.setOnSelectListener(new WheelView.OnSelectListener() {
            @Override
            public void endSelect(int id, String text) {
                viewModel.endMin.setValue((byte) id);
                viewModel.end.setValue(Utils.getString(R.string.notify_time,
                        binding.wvEndHour.getSelectedText(), text, binding.wvEndAmOrPm.getSelectedText()));
            }

            @Override
            public void selecting(int id, String text) {

            }
        });
        binding.wvEndAmOrPm.setData(aps);
        binding.wvEndAmOrPm.setOnSelectListener(new WheelView.OnSelectListener() {
            @Override
            public void endSelect(int id, String text) {
                viewModel.endAp.setValue((byte) id);
                viewModel.end.setValue(Utils.getString(R.string.notify_time,
                        binding.wvEndHour.getSelectedText(), binding.wvEndMin.getSelectedText(),text));
            }

            @Override
            public void selecting(int id, String text) {

            }
        });
    }

    private void bindEvent(){
        bindEdit();
        bindProgress();
        bindTime();
        bindTmpAndHum();
        bindCycle();
    }

    private void bindEdit(){
        ok=Utils.getString(R.string.tip_ok);
        viewModel.nameEdit.observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                if(ok.equals(s)){
                    binding.etEditName.setEnabled(true);
                    binding.etEditName.setFocusable(true);
                    binding.etEditName.setFocusableInTouchMode(true);
                    InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
                    if (imm != null) {
                        binding.etEditName.requestFocus();
                        imm.showSoftInput(binding.etEditName, 0);
                        binding.etEditName.setSelection(binding.etEditName.getText().length());
                    }
                }else{
                    binding.etEditName.clearFocus();
                    binding.etEditName.setEnabled(false);
                }
            }
        });
        viewModel.startEdit.observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                if(ok.equals(s)){
                    binding.elStartTime.expand();
                }else{
                    binding.elStartTime.collapse();
                }
            }
        });
        viewModel.endEdit.observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                if(ok.equals(s)){
                    binding.elEndTime.expand();
                }else{
                    binding.elEndTime.collapse();
                }
            }
        });
    }

    private void bindProgress(){
        now=viewModel.on;
        viewModel.on.observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(@Nullable Boolean aBoolean) {
                if(aBoolean==Boolean.TRUE&&now!=viewModel.on){
                    now.setValue(false);
                    now=viewModel.on;
                }
            }
        });
        viewModel.off.observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(@Nullable Boolean aBoolean) {
                if(aBoolean==Boolean.TRUE&&now!=viewModel.off){
                    now.setValue(false);
                    now=viewModel.off;
                }
            }
        });
        viewModel.cycle.observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(@Nullable Boolean aBoolean) {
                if(aBoolean==Boolean.TRUE){
                    binding.elCycle.expand();
                    if(now!=viewModel.cycle){
                        now.setValue(false);
                        now=viewModel.cycle;
                    }
                }else{
                    binding.elCycle.collapse();
                }
            }
        });
        viewModel.tmpHum.observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(@Nullable Boolean aBoolean) {
                if(aBoolean==Boolean.TRUE){
                    binding.elTmpHum.expand();
                    if(now!=viewModel.tmpHum){
                        now.setValue(false);
                        now=viewModel.tmpHum;
                    }
                }else{
                    binding.elTmpHum.collapse();
                }
            }
        });
    }

    private void bindTime(){
        viewModel.startHour.observe(this, new Observer<Byte>() {
            @Override
            public void onChanged(@Nullable Byte param) {
                if(binding.wvStartHour.getSelected()!=param){
                    binding.wvStartHour.setDefault(param);
                }

            }
        });
        viewModel.startMin.observe(this, new Observer<Byte>() {
            @Override
            public void onChanged(@Nullable Byte param) {
                if(binding.wvStartMin.getSelected()!=param){
                    binding.wvStartMin.setDefault(param);
                }
            }
        });
        viewModel.startAp.observe(this, new Observer<Byte>() {
            @Override
            public void onChanged(@Nullable Byte param) {
                if(binding.wvStartAmOrPm.getSelected()!=param){
                    binding.wvStartAmOrPm.setDefault(param);
                }
            }
        });
        viewModel.endHour.observe(this, new Observer<Byte>() {
            @Override
            public void onChanged(@Nullable Byte param) {
                if(binding.wvEndHour.getSelected()!=param){
                    binding.wvEndHour.setDefault(param);
                }
            }
        });
        viewModel.endMin.observe(this, new Observer<Byte>() {
            @Override
            public void onChanged(@Nullable Byte param) {
                if(binding.wvEndMin.getSelected()!=param){
                    binding.wvEndMin.setDefault(param);
                }
            }
        });
        viewModel.endAp.observe(this, new Observer<Byte>() {
            @Override
            public void onChanged(@Nullable Byte param) {
                if(binding.wvEndAmOrPm.getSelected()!=param){
                    binding.wvEndAmOrPm.setDefault(param);
                }
            }
        });
    }

    private void bindTmpAndHum(){
        viewModel.hTmp.observe(this, new Observer<Character>() {
            @Override
            public void onChanged(@Nullable Character character) {
                if(binding.cpHighTmp.getProgress()!=character){
                    binding.cpHighTmp.setProgress(character);
                }
            }
        });
        viewModel.lTmp.observe(this, new Observer<Character>() {
            @Override
            public void onChanged(@Nullable Character character) {
                if(binding.cpLowTmp.getProgress()!=character){
                    binding.cpLowTmp.setProgress(character);
                }
            }
        });
        viewModel.hHum.observe(this, new Observer<Byte>() {
            @Override
            public void onChanged(@Nullable Byte param) {
                if(binding.cpHighHum.getProgress()!=param){
                    binding.cpHighHum.setProgress(param);
                }
            }
        });
        viewModel.lHum.observe(this, new Observer<Byte>() {
            @Override
            public void onChanged(@Nullable Byte param) {
                if(binding.cpLowHum.getProgress()!=param){
                    binding.cpLowHum.setProgress(param);
                }
            }
        });
        viewModel.hTmpSwitch.observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(@Nullable Boolean param) {
                if(binding.cpHighTmp.isChecked()!=param){
                    binding.cpHighTmp.setChecked(param);
                }
            }
        });
        viewModel.lTmpSwitch.observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(@Nullable Boolean param) {
                if(binding.cpLowTmp.isChecked()!=param){
                    binding.cpLowTmp.setChecked(param);
                }
            }
        });
        viewModel.hHumSwitch.observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(@Nullable Boolean param) {
                if(binding.cpHighHum.isChecked()!=param){
                    binding.cpHighHum.setChecked(param);
                }
            }
        });
        viewModel.lHumSwitch.observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(@Nullable Boolean param) {
                if(binding.cpLowHum.isChecked()!=param){
                    binding.cpLowHum.setChecked(param);
                }
            }
        });
    }

    private void bindCycle(){
        viewModel.cycleOn.observe(this, new Observer<Character>() {
            @Override
            public void onChanged(@Nullable Character character) {
                if(binding.apCycleOn.getProgress()!=character){
                    binding.apCycleOn.setProgress(character/10);
                }
            }
        });
        viewModel.cycleOff.observe(this, new Observer<Character>() {
            @Override
            public void onChanged(@Nullable Character character) {
                if(binding.apCycleOff.getProgress()!=character){
                    binding.apCycleOff.setProgress(character/10);
                }
            }
        });
    }

    private ArrayList<String> initTime(int start, int end, boolean addZero){
        ArrayList<String> list=new ArrayList<>(end-start+1);
        if(addZero){
            int i=start;
            if(start<10){
                int max= Math.min(end, 10);
                while(i<max){
                    list.add("0"+i);
                    ++i;
                }
            }
            while(i<=end){
                list.add(String.valueOf(i));
                ++i;
            }
        }else{
            for(int i=start; i<=end; ++i){
                list.add(String.valueOf(i));
            }
        }
        return list;
    }

    private void registerMessage(){
        Messenger.getDefault().register(this, NotificationActivity.SHOW_DELETE_DIALOG, new BindingAction() {
            @Override
            public void call() {
                showDelete();
            }
        });
    }

    private void unregisterMessage(){
        Messenger.getDefault().unregister(this);
    }

    private void showDelete(){
        View view=LayoutInflater.from(getContext()).inflate(com.eternal.res.R.layout.reconfirm_dialog, null, false);
        final MaterialDialog dialog=new MaterialDialog.Builder(getContext())
                .backgroundColor(0x00ffffff)
                .customView(view, false)
                .build();
        view.findViewById(com.eternal.res.R.id.tv_cancel)
                .setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dialog.dismiss();
                    }
                });
        view=dialog.getCustomView();
        view.findViewById(com.eternal.res.R.id.tv_confirm)
                .setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        viewModel.delete();
                        dialog.dismiss();
                    }
                });
        dialog.show();
    }
}
